# ~*~ coding: utf-8 ~*~
import time
import traceback
from flask import current_app

from .models import Task, AdHoc
from .inventory import BeesInventory
from .ansible.runner import AdHocRunner, AnsibleError
from apps.extensions import db


def update_or_create_ansible_task(
        task_name, create_by, hosts, tasks, pattern='all',
        options=None, run_as=None, become=None, run_as_admin=True
):
    if not task_name or not hosts or not tasks:
        return

    # task process
    task = db.session.query(Task).filter_by(name=task_name).first()
    if not task:
        defaults_task = {
            'name': task_name,
            'create_by': create_by,
        }
        task = Task.create(**defaults_task, commit=False)
        db.session.flush()

    # adhoc process
    adhoc = db.session.query(AdHoc).filter(
                AdHoc.task_id == task.id,
                AdHoc.tasks == tasks,
                AdHoc.hosts == hosts,
                AdHoc.become == become,
                AdHoc.run_as == run_as,
                AdHoc.pattern == pattern,
                AdHoc.options == options,
                AdHoc.run_as_admin == run_as_admin
            ).first()
    if not adhoc:
        # defaults_adhoc = {
        #     'task_id': task.id,
        #     'tasks': tasks,
        #     'options': options,
        #     'hosts': hosts,
        #     'become': become,
        #     'run_as': run_as,
        #     'pattern': pattern,
        #     'run_as_admin': run_as_admin
        # }
        # AdHoc.create(**defaults_adhoc, commit=False)
        adhoc = AdHoc()
        adhoc.task_id = task.id
        adhoc.tasks = tasks
        adhoc.options = options
        adhoc.hosts = hosts
        adhoc.become = become
        adhoc.run_as = run_as
        adhoc.pattern = pattern
        adhoc.run_as_admin = run_as_admin
        adhoc.create_time = time.time()
        db.session.add(adhoc)
    else:
        adhoc.create_time = time.time()

    db.session.commit()
    return task


def run_ansible_task(
        task_name, hosts, tasks,
        pattern='all', options=None,
        run_as=None, become=None,
        run_as_admin=True
):

    inventory = BeesInventory(
        hosts=hosts, run_as=run_as, become=become, run_as_admin=run_as_admin
    )
    options = options or {'timeout': 120, 'forks': 10}
    runner = AdHocRunner(inventory, options=options)

    tasks = tasks  # [{},{}]
    pattern = pattern   # All
    task_name = task_name
    try:
        result = runner.run(
            tasks,
            pattern,
            task_name,
        )
        return result.results_raw, result.results_summary
    except AnsibleError as e:
        current_app.logger.error(traceback.format_exc())
